//////////////////////////////////////////////////////////////////////////////////////////////
//	File			:	"Entity.cpp"
//
//	Author			:	Mike Davis, Matt Stover, James Thornton, Keith Webster
//	
//	Project			:	TacWars
//
//	Last Modified	:	11/6/2013
//
//	Purpose			:	
//
//////////////////////////////////////////////////////////////////////////////////////////////

#include "Entity.h"
#include <cassert>
#include "../Game.h"
#include "../../SGD Wrappers/CSGD_Direct3D.h"
#include "../../SGD Wrappers/CSGD_DirectInput.h"
#include "../../SGD Wrappers/CSGD_TextureManager.h"
#include "../../SGD Wrappers/CSGD_XAudio2.h"
#include "../Animation/AnimInfo.h"
#include "../../SGD Wrappers/CSGD_EventSystem.h"
#include "../../SGD Wrappers/CSGD_MessageSystem.h"
#include "../StateMachine/GameplayState.h"
#include "../MapSystem/BattleMap.h"
#include "../MessageSystem/UnitDeadMessage.h"
#include "../MessageSystem/UnitTurnEndMessage.h"
#include "../GameObjects/PrecisionGauge.h"


Entity::Entity()
{
	Type = GENERAL;
	State = IDLE;
	myInfo = new AnimInfo;
	moveRange = attackRange = attackDamage = Health = Loyalty = abilityCooldown = 0;
	abilityRange = imageID = posX = posY = 0;
	Height = Width = 0;
	hasFlag = isBuffed = isScared = isNeutral = hasMoved = moveAnimation = false;
	showMove = showAttack =  false;
	maxHP = maxLP = 100;

	refCount = 1;

	CSGD_EventSystem::GetInstance()->RegisterClient("UNIT_DEAD", this);
	CSGD_EventSystem::GetInstance()->RegisterClient("UNIT_DAMAGED", this);

}
Entity::~Entity()
{
}
/*virtual*/ void Entity::Update( float fElapsedTime)
{

	if(this->GetHealth() <= 0)
	{
		this->State = DEAD;
	}

	switch(State)
	{
	case IDLE:
		{

		}
		break;
	case MOVE:
		{
			hasMoved = true;
		}
		break;
	case ACTION:
		{

		}
		break;
	case ATTACK:
		{

		}
		break;
	case ABILITY:
		{

		}
		break;
	case FINISH:
		{
			UnitTurnEndMessage* createMsg = new UnitTurnEndMessage(this);
			CSGD_MessageSystem::GetInstance()->QueueMessage(createMsg);
			createMsg = nullptr;
			//CSGD_EventSystem::GetInstance()->SendEventNow("UNIT_FINISHED", nullptr, nullptr, this);
			//Owner->RemoveUnit(this, Owner->AvailableUnits);
		}
		break;
	case DEAD:
		{
			UnitDeadMessage* createMsg = new UnitDeadMessage(this);
			CSGD_MessageSystem::GetInstance()->QueueMessage(createMsg);
			createMsg = nullptr;
			//CSGD_EventSystem::GetInstance()->SendEventNow("UNIT_DEAD", nullptr, nullptr, this);
			//Owner->RemoveUnit(this, Owner->Squad);
		}
		break;
	}
}
/*virtual*/ void Entity::Render( void )
{
	if(showMove)
	{
		int tempCamX = GameplayState::GetInstance()->GetCamX();
		int tempCamY = GameplayState::GetInstance()->GetCamY();

		RECT temp = {(GetPosX() - (64* moveRange)) - tempCamX, 
			(GetPosY() - (64* moveRange)) -  tempCamY, 
			(GetPosX() + (64 * (moveRange+1))) - tempCamX, 
			(GetPosY() + (64 * (moveRange+1))) - tempCamY};
		moveRect = temp;

		CSGD_Direct3D::GetInstance()->DrawRect(moveRect, D3DCOLOR_ARGB(100,0,0,255));
	}
	if(showAttack)
	{
		int tempCamX = GameplayState::GetInstance()->GetCamX();
		int tempCamY = GameplayState::GetInstance()->GetCamY();

		RECT temp = {(GetPosX() - (64* attackRange)) - tempCamX, 
			(GetPosY() - (64* attackRange)) -  tempCamY, 
			(GetPosX() + (64 * (attackRange+1))) - tempCamX, 
			(GetPosY() + (64 * (attackRange+1))) - tempCamY};
		attackRect = temp;


		CSGD_Direct3D::GetInstance()->DrawRect(attackRect, D3DCOLOR_ARGB(100,255,0,0));
	}

	showMove = showAttack = false;

	if(moveAnimation)
	{
		assert(imageID != -1 && "Entity::Render - image not set");
		myInfo = GetAnimInfo();
		int testx = GetPosX();
		CAnimationManager::GetInstance()->RenderAnimation(myInfo->currAnimation, *myInfo, this);
	}
	else
	{
		assert(imageID != -1 && "Entity::Render - image not set");
		CSGD_TextureManager::GetInstance()->Draw(imageID, posX - GameplayState::GetInstance()->GetCamX(),
			posY - GameplayState::GetInstance()->GetCamY(), 1.0f, 1.0f, nullptr, Width/2, Height/2);
	}

}
/*virtual*/ RECT Entity::GetRect( void ) const
{
	RECT rect = {0,0,0,0};

	return rect;
}
/*virtual*/ void Entity::HandleCollision( const IEntity* pOther )
{

}
/*virtual*/ void Entity::HandleEvent( const CEvent* pEvent)
{
	if(pEvent->GetEventID() == "UNIT_DAMAGED" && pEvent->GetDestination() == this)
	{
		/*int* dmghp =  reinterpret_cast<int *>(pEvent->GetParam());
		if(dmghp != nullptr)
		this->SetHealth(this->GetHealth() - *dmghp);*/
		//just to prove it works
		this->SetHealth(0);
		if(this->GetHealth() <= 0)
		{
			this->State = DEAD;
			Owner->RemoveUnit(this, Owner->Squad);
		}
	}
	//if(pEvent->GetEventID() == "UNIT_DEAD" /*&& pEvent->GetDestination() == this*/)
	//{
	//	//this->State = DEAD;
	//	
	//	Owner->RemoveUnit(this, Owner->Squad);
	//}
}
/*virtual*/ void Entity::AddRef ( void )
{
	assert(refCount != UINT_MAX && "Entity::AddRef - refcount exceeded max");
	++refCount;
}
/*virtual*/ void Entity::Release( void )
{
	--refCount;
	if(refCount == 0)
		delete this;
}
/*virtual*/ void Entity::Move(TileM* tile)
{
	//this logic should work for everyone

	if(CanIMoveHere(tile) == true && tile->OccupyingUnit == nullptr)
	{
		this->occupyingTile->OccupyingUnit = nullptr;
		posX = tile->position.x;
		posY = tile->position.y;
		tile->OccupyingUnit = this;
		this->occupyingTile = tile;
	}
}
/*virtual*/ void Entity::Attack(Entity* target)
{
	if(CanIAttackHere(target->occupyingTile) == true)
	{
		if(this->Owner != target->Owner && target->isNeutral == false)
		{
			/*Gauge = new PrecisionGauge;
			GameplayState::GetInstance()->EndPG();
			Gauge->DamageCalculation(target,this->GetAttackDamage());*/

		}
	}
}
/*virtual*/ void Entity::UseAbility()
{

}
/*virtual*/ void Entity::Capture(EntityObject* object)
{
	//if(this->isCapping == true && object.type == POWERNODE)
	//{
	//	object.Activate();
	//}
	//else if(this->isCapping == false && object.type == POWERNODE)
	//{
	//	this->isCapping = true;
	//}
	//else if(object.type == FLAG)
	//{
	//	this->hasFlag = true;
	//	object.Activate();
	//}
}
/*virtual*/ void Entity::ShowMoveRange()
{
	int tempCamX = GameplayState::GetInstance()->GetCamX();
		int tempCamY = GameplayState::GetInstance()->GetCamY();

		RECT temp = {(GetPosX() - (64* moveRange)) - tempCamX, 
			(GetPosY()  - (64* moveRange)) -  tempCamY, 
			(GetPosX()  + (64 * (moveRange+1))) - tempCamX, 
			(GetPosY() + (64 * (moveRange+1))) - tempCamY};
		moveRect = temp;

		CSGD_Direct3D::GetInstance()->DrawRect(moveRect, D3DCOLOR_ARGB(100,0,0,255));
	//showMove = true;
	//int tempCamX = GameplayState::GetInstance()->GetCamX();
	//int tempCamY = GameplayState::GetInstance()->GetCamY();

	//RECT temp = {(GetPosX() - (64* moveRange)) - tempCamX, 
	//	(GetPosY() - (64* moveRange)) -  tempCamY, 
	//	(GetPosX() + (64 * moveRange)) - tempCamX, 
	//	(GetPosY() + (64 * moveRange)) - tempCamY};
	//moveRect = temp;
	//for(int i = 0; i < this->moveRange; i++)
	//{
	//	
	//}
}
/*virtual*/ void Entity::ShowAttackRange()
{
			int tempCamX = GameplayState::GetInstance()->GetCamX();
		int tempCamY = GameplayState::GetInstance()->GetCamY();

		RECT temp = {(GetPosX() - (64* attackRange)) - tempCamX, 
			(GetPosY() - (64* attackRange)) -  tempCamY, 
			(GetPosX() + (64 * (attackRange+1))) - tempCamX, 
			(GetPosY() + (64 * (attackRange+1))) - tempCamY};
		attackRect = temp;


		CSGD_Direct3D::GetInstance()->DrawRect(attackRect, D3DCOLOR_ARGB(100,255,0,0));
}
/*virtual*/ bool Entity::CanIMoveHere(TileM* tile)
{
	if(abs(tile->position.x - posX)/100 <= moveRange && abs(tile->position.y - posY)/100 <= moveRange)
	{
		return true;
	}
	else
		return false;
}
/*virtual*/ bool Entity::CanIAttackHere(TileM* tile)
{
	if(abs(tile->position.x - posX)/100 <= attackRange && abs(tile->position.y - posY)/100 <= attackRange)
	{
		return true;
	}
	else
		return false;
}